<?php
if( !APP_ROOT )
    return 'Direct Access Deny!';
    
use libraries\Verify;
use libraries\Benchmark;
use libraries\RQueue;
use libraries\RedisSession;
use enums\HttpServerEnums;
use libraries\CommUtils;
use libraries\DExclusiveLock;
use enums\EmailEnums;
use libraries\XEMail;
use enums\ServiceEnums;

// $config = $di->get( 'config', require APP_ROOT . 'config/config.php' );
// Set a different connection in each module
$config = $di['config'];
	

$di->set( ServiceEnums::SERVICE_BENCHMARK, function(){
    
    $bm = new Benchmark();
    return $bm;
}, true);



$di->set( ServiceEnums::SERVICE_COOKIES, function()
{
	if( CommUtils::getServerType() == HttpServerEnums::SERVER_TYPE_COMMON )
	{
		$cookies = new \Phalcon\Http\Response\Cookies();
		// 		$cookies = new \libraries\CookiesCommon();
	}
	else
	{
		$cookies = new \libraries\CookiesSwoole();
		$cookies->setDI( $this );
	}

	$cookies->useEncryption( true );

//	ini_set("session.cookie_httponly", 1);
	//  	ini_set( 'session.cookie_path', 1 );
	return $cookies;
});

$di->set( ServiceEnums::SERVICE_SESSION, function(){
    if( !extension_loaded( 'redis' ))
    {
        return 'redis extension not loaded!<br>';
    }
//    ini_set( 'session.name', HttpServerEnums::SESSION_KEY );
    if( CommUtils::getServerType() == HttpServerEnums::SERVER_TYPE_COMMON )
    {
    	$session = new \Phalcon\Session\Adapter\Redis( $this['sessionCfg']->redisServer->toArray());
    	$session->start();
    	
    }
    else
    {//$config->cache->htmlCache->frontend
		$redis = new \Redis();

    	$redis->connect( $this['sessionCfg']->redisServer->host, $this['sessionCfg']->redisServer->port );
    	$redis->auth( $this['sessionCfg']->redisServer->auth );
    	$redis->select( $this['sessionCfg']->redisServer->index );
    	
    	$this->redisSession = $redis;
    	$session = new RedisSession( $this );
    }
    return $session;
}, true );

$di->set( 'crypt', function(){
	$crypt = new \phalcon\Crypt();
	$crypt->setKey('#&dj9$=as?.ak//j1V$yhfk'); // Use your own key!
	return $crypt;
});

// Registering a router
$di->set( ServiceEnums::SERVICE_ROUTER,function () {
    
    require_once APP_ROOT . 'config/router.php';
    return $router;
}, true );

// Registering unitTest
$di->set( ServiceEnums::SERVICE_UNIT_TEST, function () {
    return new \libraries\UnitTest();
}, true );

$di->set( 'url', function(){
    $url = new Phalcon\Mvc\Url();
    $url->setBaseUri( $this['config']->application->baseUri );
    return $url;
}, true );

// 验证码
$di->set( ServiceEnums::SERVICE_VERIFY, function(){
    $verify = new Verify();
    $verify->setDI( $this );
    return $verify;
}, true );

// //////////////////////////////////////////////////////////////////////////////////////////////////////////
// cache
/**
 * for html segment
 */
$di->set( ServiceEnums::SERVICE_HTML_CACHE, function(){

    if( !file_exists( $this['cacheCfg']->htmlCache->backend->cacheDir . 'html/' ) && !mkdir( $this['cacheCfg']->htmlCache->backend->cacheDir . 'html/' ) )
    {
        var_dump( error_get_last() );
        return;
    }

    $frontCache = new \Phalcon\Cache\FrontEnd\Output( $this['cacheCfg']->htmlCache->frontend->toArray() ); // cache two days
    
    $cache = new \Phalcon\Cache\Backend\File( $frontCache, $this['cacheCfg']->htmlCache->backend->toArray() );
    return $cache;
}, true );



/**
 * memory 易失性 不能进行序列化 只能在一次请求中有效
 */
$di->set( 'memory', function (){
    
    $frontCache = new \Phalcon\Cache\FrontEnd\Data( $this['cacheCfg']->inmem->frontend->toArray() );
    $cache = new \Phalcon\Cache\Backend\Memory( $frontCache );

    return $cache;
}, true );



/**
 * redis cache
 */
$di->set( ServiceEnums::SERVICE_REDIS_CACHE, function(){
    
    if( !extension_loaded( 'redis' ))
    {
        return 'redis extension not loaded!<br>';
    }
    
    $frontCache = new \Phalcon\Cache\FrontEnd\Data( $this['cacheCfg']->redisCache->frontend->toArray() );
    $cache = new \Phalcon\Cache\Backend\Redis( $frontCache, $this['cacheCfg']->redisCache->backend->toArray() );

    return $cache;
}, true );


/**
 * local native redis server
 */
$di->set( ServiceEnums::SERVICE_NATIVE_REDIS, function()
{
	if( !extension_loaded( 'redis' ) )
	{
		echo 'redis extension not loaded!<br>';
		exit();
	}

	$redis = new \Redis();
	$redis->connect( $this['cacheCfg']->redisCache->backend->host, $this['cacheCfg']->redisCache->backend->port /*, 'password'*/ );
	$redis->auth( $this['cacheCfg']->redisCache->backend->auth );
	$redis->select( $this['cacheCfg']->redisCache->backend->index );

	return $redis;
}, true );

    
$di->set( ServiceEnums::SERVICE_RQUEUE, function(){
    if( !extension_loaded( 'redis' ) )
    {
        echo 'redis extension not loaded!<br>';
        exit();
    }
    
    $redis = new \Redis();
    $redis->connect( $this['queueCfg']->server->host, $this['queueCfg']->server->port );
    $redis->auth( $this['queueCfg']->server->auth );
    $redis->select( $this['queueCfg']->server->index );
    
    $rq = new RQueue();
    $rq->setServer( $redis );
    
    return $rq;

}, true );


//-----------------------------------------
// email service
//-----------------------------------------
$di->set( ServiceEnums::SERVICE_EMAIL, function() {
    
//	require_once APP_ROOT . 'vendors/swiftmailer/lib/swift_required.php';
	
 	if( EmailEnums::MODE_LOCAL == $this['emailCfg']->mode )
 	{
 	    $transport = new \Swift_SendmailTransport();
// 		$transport = Swift_SendmailTransport::newInstance( $this['emailCfg']->{EmailEnums::MODE_LOCAL}->sendmail );
 	}
 	else
 	{
 	    $transport = new \Swift_SmtpTransport($this['emailCfg']->{ EmailEnums::MODE_ONLINE }->smtp_host,
            $this['emailCfg']->{ EmailEnums::MODE_ONLINE }->smtp_port);

 		$transport->setUsername( $this['emailCfg']->{ EmailEnums::MODE_ONLINE }->smtp_user )
                  ->setPassword( $this['emailCfg']->{ EmailEnums::MODE_ONLINE }->smtp_pass );
 	}
 	
// 	$mailer = Swift_Mailer::newInstance( $transport );
 	$mailer = new \Swift_Mailer( $transport );
 	
 	$mail = XEMail::getInstance( $mailer, $this );
 	
    return $mail;
    
}, true );


/**
 * redis distribution lock db
 */
$di->set( ServiceEnums::SERVICE_REDIS_DB_LOCK, function(){
	
	$redis = new \Redis();
	
	$redis->connect( $this['lockCfg']->redisServer->host, $this['lockCfg']->redisServer->port /*, 'password'*/ );
	$redis->auth( $this['lockCfg']->redisServer->auth );
	$redis->select( $this['lockCfg']->redisServer->index );
	
	return $redis;
}, true);
//-----------------------------------------
// lock service
//-----------------------------------------
$di->set( ServiceEnums::SERVICE_DISTRIBUTION_EXCLUSIVE_LOCK, function(){
    return DExclusiveLock::getInstance( $this );
} );



$di->set( ServiceEnums::SERVICE_MODELS_META_DATA,function(){ 
    
	$metaData = new \Phalcon\Mvc\Model\MetaData\Memory( array(
		'lifetime' => 1440,
	    'prefix' => 'metadata_'
	));
	return $metaData;
}, true );


/**
 * CsrfCheck
 */
$di->set( ServiceEnums::SERVICE_SECURITY, function(){
    return new \libraries\CsrfCheck();
}, true );


$di->set( ServiceEnums::SERVICE_BIZ_LOG, function(){
	
	if( !file_exists( $this['logCfg']->log->bizLogPath ))
	{
		$logFile = fopen( $this['logCfg']->log->bizLogPath, 'a' );
		
		if( false !== $logFile )
		{
			fclose( $logFile );
		}
		else
		{//error
			
		}	
	}
	
    $logger = new Phalcon\Logger\Adapter\File( $this['logCfg']->log->bizLogPath );
    return $logger;
    
}, true );

$di->set( ServiceEnums::SERVICE_ERR_LOG, function(){
	
	if( !file_exists( $this['logCfg']->log->errLogPath ))
	{
		$logFile = fopen( $this['logCfg']->log->errLogPath, 'a'  );
	
		if( false !== $logFile )
		{
			fclose( $logFile );
		}
		else
		{//error
				
		}
	}
	
    $logger = new Phalcon\Logger\Adapter\File( $this['logCfg']->log->errLogPath );
    return $logger;
}, true );


$di->set( ServiceEnums::SERVICE_DEBUG_LOG, function(){
	
	if( !file_exists( $this['logCfg']->log->debugLogPath ))
	{
		$logFile = fopen( $this['logCfg']->log->debugLogPath, 'a'  );
	
		if( false !== $logFile )
		{
			fclose( $logFile );
		}
		else
		{//error
				
		}
	}
	$logger = new Phalcon\Logger\Adapter\File( $this['logCfg']->log->debugLogPath );
	return $logger;
}, true );
